﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Miner.Controllers.Interfaces;
using Miner.Model.Logic;
using Miner.UI.Controls.Interfaces;

namespace MinerMiner.Controllers
{
    class DrawingArea: IDrawingArea
    {
        #region Members
        private Graphics g;
        private IDrawAreaCtrl area;
        private Bitmap buffer;
        private int xBlockCount;
        private int yBlockCount;
        private int blockSize;

        private Image hiddenImg;
        private Image oEmptyImg;
        private Image oMineImg;
        private Image oInfoImg;
        private Image markedImg; 
        #endregion

        #region Ctor
        public DrawingArea(GameOptions opt, IDrawAreaCtrl drawArea, string imgDir)
        {
            this.area = drawArea;
            this.xBlockCount = opt.xBlocksCount * opt.BlockSize;
            this.yBlockCount = opt.yBlocksCount * opt.BlockSize;
            this.blockSize = opt.BlockSize;
            this.buffer = new Bitmap(this.xBlockCount, this.yBlockCount);
            this.g = Graphics.FromImage(buffer);

            if (!LoadBlockSprites(imgDir))
            {
                MessageBox.Show("Path : " + imgDir + " is not valid");
            }
        } 
        #endregion

        #region IDrawingArea
        public void DrawHiddenBlock(MPoint p)
        {
            putSprite(hiddenImg, p);
        }

        public void DrawOpenedEmptyBlock(MPoint p)
        {
            putSprite(oEmptyImg, p);
        }

        public void DrawOpenedInfoBlock(MPoint p)
        {
            putSprite(oInfoImg, p);
        }

        public void DrawOpenedMineBlock(MPoint p)
        {
            putSprite(oMineImg, p);
        }

        public void DrawMarkedBlock(MPoint p)
        {
            putSprite(markedImg, p);
        }

        public void DrawText(MPoint p, string text)
        {
            g.DrawString(text, new Font("Tahoma", 9), Brushes.Black, p.x * blockSize + 4, p.y * blockSize + 4);
            Refresh();
        } 
        #endregion

        #region Tools
        private void putSprite(Image img, MPoint p)
        {
            g.DrawImage(img, p.x * blockSize, p.y * blockSize);
            Refresh();
        }

        private void Refresh()
        {
            this.area.Image = buffer;
        }

        private bool LoadBlockSprites(string imgDir)
        {
            if (imgDir != null && imgDir != string.Empty)
            {
                try
                {
                    this.hiddenImg = Image.FromFile(imgDir + @"\hiddenBlock.bmp");
                    this.oEmptyImg = Image.FromFile(imgDir + @"\emptyBlock.bmp");
                    this.oInfoImg = Image.FromFile(imgDir + @"\infoBlock.bmp");
                    this.oMineImg = Image.FromFile(imgDir + @"\mineBlock.bmp");
                    this.markedImg = Image.FromFile(imgDir + @"\markedBlock.bmp");

                    return true;
                }
                catch (OutOfMemoryException e)
                { }
                catch (FileNotFoundException e)
                { }
                catch (Exception e)
                { }
            }
            return false;
        } 
        #endregion
    }
}
